using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Survival.Services;


namespace Survival.Components
{

    //public class MouseEvent
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class InputHandler : Microsoft.Xna.Framework.GameComponent , IInputService
    {
        private KeyboardState oldKeyState;
        private KeyboardState currentKeyState;
        private MouseState currentMouseState;
        private MouseState oldMouseState;
        private Vector2 mouseVector;
        private IDebugTextService debugText;
        //TODO: Make a stopwatch debugging class   

        public EventHandler<MouseEventArgs> MouseEventHandler;
        public Vector2 MousePositionVector { get { return mouseVector; } }


        public InputHandler(Game game)
            : base(game)
        {
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            SetInitialStates();
            base.Initialize();
            debugText = (IDebugTextService)Game.Services.GetService(typeof(IDebugTextService));
        }

        private void SetInitialStates()
        {
            oldKeyState = Keyboard.GetState();
            oldMouseState = Mouse.GetState();
            Game.IsMouseVisible = true;
        }
        private void SetCurrentStates()
        {
            currentKeyState = Keyboard.GetState();
            if(Game.IsActive)
                currentMouseState = Mouse.GetState();
        }

        private void SetOldStates()
        {
            oldKeyState = currentKeyState;
            oldMouseState = currentMouseState;
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            SetCurrentStates();

            // Allows the game to exit
            if (KeyPressed(Keys.Escape))
                Game.Exit();

            UpdateMouseVector();
            if (MouseClickLeft())
            {
                OnLeftclickEvent();
            }

            SetOldStates();
            //debugText.DrawString(new DrawableString(mouseVector.ToString(), mouseVector));
            base.Update(gameTime);
        }

        private void UpdateMouseVector()
        {
            if (Game.IsActive)
            {
                mouseVector.X = currentMouseState.X;
                mouseVector.Y = currentMouseState.Y;
            }
        }

        public bool KeyPressed(Keys key)
        {
            if (currentKeyState.IsKeyDown(key))
            {
                if (oldKeyState.IsKeyUp(key))
                    return true;
            }
            return false;
        }

        private void OnLeftclickEvent()
        {
            EventHandler<MouseEventArgs> handler = MouseEventHandler;

            // Event will be null if there are no subscribers
            if (handler != null)
            {
                MouseEventArgs e = new MouseEventArgs(mouseVector);

                // Use the () operator to raise the event.
                handler(this, e);
            }
        }

        private bool MouseClickLeft()
        {
            if (currentMouseState.LeftButton == ButtonState.Pressed)
            {
                if (oldMouseState.LeftButton == ButtonState.Released)
                    return true;
            }
            return false;
        }

        private bool MouseClickRight()
        {
            if (currentMouseState.RightButton == ButtonState.Pressed)
            {
                if (oldMouseState.RightButton == ButtonState.Released)
                    return true;
            }
            return false;
        }

        bool IInputService.KeyPressed(Keys key)
        {
            return Keyboard.GetState().IsKeyDown(key);
        }


        public MouseState MouseState
        {
            get { return MouseState; }
        }

    }

    public class MouseEventArgs : EventArgs
    {
        Vector2 mousePosition;

        public Vector2 MousePosition { get { return mousePosition; } }

        public MouseEventArgs(Vector2 position)
        {
            mousePosition = position;
        }
    }
}
